package net.linlan.plat.handler;

import net.linlan.annotation.AuthLogin;
import net.linlan.frame.FramePubUser;
import net.linlan.plat.comm.service.AuthService;
import net.linlan.plat.comm.utils.AuthReqUtils;
import net.linlan.sys.web.KernelConstant;
import net.linlan.sys.web.RedisService;
import net.linlan.utils.http.HttpContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;


/**
 *
 * Filename:MemberLoginResolver.java
 * Desc:@LoginUser注解的方法参数，注入当前登录用户
 *
 * @author Linlan
 * CreateTime:2017/12/10 23:09
 * ModifyTime:2020/11/26 23:09
 *         modify 20201126，对于pub模式，用户未登录等情况存在，
 *         由于用户未登录，入口设置了AuthLogin，此时需要进入用户的信息赋值和返回
 *
 * @version 1.0
 * @since 1.0
 *
 */
@Component
public class ApiMemberLoginResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(FramePubUser.class)
                && parameter.hasParameterAnnotation(AuthLogin.class);
    }

    /**通过从request内获取用户信息，并将用户信息设置到Session内，以实现直接的获取
     * @param parameter     方法参数
     * @param container     页面容器
     * @param request       request请求
     * @param factory       应用工厂
     * @return              用户对象
     * @throws Exception    异常
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        //获取用户ID
        HttpServletRequest httpServletRequest = HttpContextUtils.getHttpServletRequest();
        Object object = AuthReqUtils.getMemberId(httpServletRequest);;

        if (object == null) {
            return null;
        }
        Long memberId = (Long) object;
        //获取用户ID
        FramePubUser user = redisService.get(AuthReqUtils.REDIS_FRAME_USER_KEY +memberId, FramePubUser.class);
        if (user == null){
            user = authService.getWorkerByMemberId(memberId);
            if (user == null) {
                return null;
            }
            //默认查询出的用户source可能为local，需要赋值
            redisService.set(AuthReqUtils.REDIS_FRAME_USER_KEY + memberId, user, KernelConstant.TEN_MINUTE_EXPIRE);
        }else{
            //20201130，将用户保存到redis里面
            redisService.set(AuthReqUtils.REDIS_FRAME_USER_KEY + memberId, user, KernelConstant.TEN_MINUTE_EXPIRE);
        }
        return user;
    }

    @Autowired
    private AuthService authService;
    @Autowired
    private RedisService redisService;

}
